package cn.com.main;

import cn.com.consts.TemplateConst;
import cn.com.utils.DockerUtil;
import cn.com.utils.FileUtil;
import cn.com.utils.HttpClientUtil;
import cn.com.utils.MachineTranslationUtil;
import cn.com.utils.ThreadPoolUtils;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SmUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.SM2;
import com.github.dockerjava.api.model.Container;
import com.github.dockerjava.api.model.Image;
import lombok.SneakyThrows;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedWriter;
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.OpenOption;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public class HutoolSMUtil {

    private static final Logger log = LoggerFactory.getLogger(HutoolSMUtil.class);
    String pri = "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgxN8XT8NQuOIWkzUlFjBZh7r7nlN9n9Qcjq8Y8qJwnLagCgYIKoEcz1UBgi2hRANCAASh84uSyH39zrVfCsmS769S1r+OXHImTjxNf6aG8gi8R9XVSTYggGeRmBP3hBSJYywrwgtybXPW9AyQCPSQxfSt";
    String pub = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEofOLksh9/c61XwrJku+vUta/jlxyJk48TX+mhvIIvEfV1Uk2IIBnkZgT94QUiWMsK8ILcm1z1vQMkAj0kMX0rQ==";

    @Test
    public void sm2Test() {

        String text = "Hello, world!";

        //使用随机生成的密钥对加密或解密
        System.out.println("使用随机生成的密钥对加密或解密====开始");
        SM2 sm2 = SmUtil.sm2();
        // 公钥加密
        String encryptStr = sm2.encryptBcd(text, KeyType.PublicKey);
        System.out.println("公钥加密：" + encryptStr);
        //私钥解密
        String decryptStr = StrUtil.utf8Str(sm2.decryptFromBcd(encryptStr, KeyType.PrivateKey));
        System.out.println("私钥解密：" + decryptStr);
        System.out.println("使用随机生成的密钥对加密或解密====结束");


        //使用自定义密钥对加密或解密
        System.out.println("使用自定义密钥对加密或解密====开始");

        byte[] privateKey = FileUtil.readBytesFromFile("src/main/resources/privateKey.pem");
        byte[] publicKey = FileUtil.readBytesFromFile("src/main/resources/publicKey.pem");

        SM2 sm22 = SmUtil.sm2(Base64.getDecoder().decode(pri), Base64.getDecoder().decode(pub));
        // 公钥加密
        String encryptStr2 = sm22.encryptBcd("text111", KeyType.PublicKey);
        System.out.println("公钥加密：" + encryptStr2);
        //私钥解密
        String decryptStr2 = StrUtil.utf8Str(sm22.decryptFromBcd(encryptStr2, KeyType.PrivateKey));
        System.out.println("私钥解密：" + decryptStr2);
        System.out.println("使用自定义密钥对加密或解密====结束");

    }


    @Test
    public void sm3Test() {
        String text = "Hello, world!";
        String digestHex = SmUtil.sm3(text);
        System.out.println("加密后：" + digestHex);
    }

    @Test
    public void sm4Test() {
        //
        //查询课题列表
        //发起申请
        //查询申请历史
        //撤销申请
        //查询当前学生所有课题
        //切换课题
        //查询当前课题详情
        //退出课题
        //
        List<String> list = new ArrayList<>();
        list.add("配额创建");
        list.add("管理员删除配额策略");
        list.add("管理员查询总配额列表");
        list.add("老师查询总配额");
        list.add("老师查询课题配额列表");
        list.add("配额更新请求体构建");
        list.add("管理员修改配额");
        list.add("老师批量修改课颖配额");
        list.add("查询老师列表");
        list.add("查询课题列表");
        list.add("发起申请");
        list.add("查询申请历史");
        list.add("撤销申请");
        list.add("查询当前学生所有课题");
        list.add("切换课题");
        list.add("查询当前课题详情");
        list.add("退出课题");
        list.add("创建课题");
        list.add("编辑课题");
        list.add("解散课题");
        list.add("切换课题");
        list.add("查询课题详情");
        list.add("教师课题列表查询");
        list.add("查询可邀请的学生列表");
        list.add("邀请历史查询");
        list.add("邀请学生");
        list.add("查询当前课题成员");
        list.add("移除成员");
        list.add("查询申请");
        list.add("申请处理");

        List<Object> collect = list.stream().map(menuName -> {

            String english = MachineTranslationUtil.toEnglish(menuName);
            english = english.trim().replaceAll("'", "");
            return allUppercase(english) + "(\"" + toCamelCase(english) + "\", \"" + menuName + "\"),";
        }).collect(Collectors.toList());
        System.out.println();
        System.out.println();
        System.out.println();
        collect.forEach(System.out::println);
    }

    public static String allUppercase(String input) {
        StringBuilder result = new StringBuilder();
        String[] parts = input.toUpperCase().split(" ");
        for (int i = 0; i < parts.length; i++) {
            result.append(parts[i]);
            result.append("_");
        }
        result.delete(result.length() - 1, result.length());
        return result.toString();
    }

    public static String toCamelCase(String input) {
        StringBuilder result = new StringBuilder();
        String[] parts = input.split(" ");
        for (int i = 0; i < parts.length; i++) {
            if (i == 0) {
                result.append(parts[i]);
            } else {
                result.append(capitalize(parts[i]));
            }
        }
        return result.toString();
    }

    public static String capitalize(String word) {
        return Character.toUpperCase(word.charAt(0)) + word.substring(1);
    }


    //测试超时
    @Test
    public void timeoutTest() throws Exception {
        System.out.println("开始测试超时" + DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
        String url = "http://10.182.0.16:30011/mock/v1/resource/machine/modify-quota";
        long timeMillis = System.currentTimeMillis();
        System.out.println(HttpClientUtil.post(url, new HashMap<>(), ""));
        long totalTime = System.currentTimeMillis() - timeMillis;
        System.out.println("结束测试超时" + DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
        //总耗时

        System.out.println("总耗时：" + totalTime);
    }

    //测试异常
    @Test
    public void exceptionTest() throws Exception {
        System.out.println(catce());

    }

    private static int catce() {
        int i = 1;
        try {
            i = i++;
            i = i / 0;
            return i;
        } catch (Exception e) {
            i = i++;
            return i;
        } finally {
            return i;
        }
    }

    //测试异步
    ThreadPoolExecutor executor = ThreadPoolUtils.threadPoolTaskExecutor();

    private static void extracted(DockerUtil dockerUtil) throws Exception {
        // Tag an image
        dockerUtil.tagImage("c49ccdef0ab0", "10.103.10.3:8003/repository-1", "v1");
        // Push an image
        dockerUtil.pushImage("10.103.10.3:8003", "repository-1");

        // Export a container
        //dockerUtil.exportContainer("container_id", "path/to/export.tar");

        // Save an image
        dockerUtil.saveImage("e45ac70e0a6d", "path/to/save.tar");

        // Load an image
        dockerUtil.loadImage("path/to/save.tar");

        // Build an image
        //String imageId = dockerUtil.buildImage("path/to/Dockerfile", "tag");
        //System.out.println("Built image ID: " + imageId);

        // Remove an image
        dockerUtil.removeImage("e45ac70e0a6d");

        // List containers
        List<Container> containers = dockerUtil.listContainers();
        for (Container container : containers) {
            System.out.println("Container ID: " + container.getId());
        }

        // List images
        List<Image> images = dockerUtil.listImages();
        for (Image image : images) {
            System.out.println("Image ID: " + image.getId());
        }
    }

    //测试dockerUtil
    @Test
    public void testDockerUtil() throws Exception {
        DockerUtil dockerUtil = new DockerUtil("tcp://192.168.247.6:2375",
                "admin",
                "1q2w3e$R",
                "your_email",
                "http://10.103.10.3:8003");
        //extracted(dockerUtil);
        // Tag an image
        dockerUtil.tagImage("c49ccdef0ab0", "10.103.10.3:8003/repository-1", "v1");
        // Push an image
    }

    @Test
    public void asyncTest() throws Exception {

        CompletableFuture.supplyAsync(() -> {
            try {
                TimeUnit.SECONDS.sleep(2);
                System.out.println(Thread.currentThread().getName() + ", 1 任务执行完成");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "0";
        }, executor).handle((res, tx) -> {
            // 处理结果数据
            return res + "1";
        }).whenComplete((res, tx) -> {
            System.out.println("获取到结果：" + res);
            if (tx != null) {
                System.err.println("发生错误了：" + tx.getMessage());
            }
            executor.shutdown();
        });

        Thread.sleep(10000);
    }

    @Test
    public void testTimeZone() {
        List<ZoneId> zoneIds = new ArrayList<>();
        zoneIds.add(ZoneId.of("UTC"));
        zoneIds.add(ZoneId.of("GMT"));
        zoneIds.add(ZoneId.systemDefault());
        zoneIds.add(ZoneId.of("America/Los_Angeles"));
        zoneIds.add(ZoneId.of("America/New_York"));
        zoneIds.add(ZoneId.of("Asia/Shanghai"));
        zoneIds.add(ZoneId.of("Europe/London"));
        zoneIds.add(ZoneId.of("Australia/Sydney"));

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        for (ZoneId zoneId : zoneIds) {
            ZonedDateTime zonedDateTime = ZonedDateTime.now(zoneId);
            System.out.println(zoneId + ": " + zonedDateTime.format(formatter));
        }
    }

    //测试docker
    @SneakyThrows
    @Test
    public void testDocker() {
        //DockerUtil dockerUtil = new DockerUtil("tcp://192.168.247.6:2375",
        //        "admin",
        //        "1q2w3e$R",
        //        "your_email",
        //        "http://10.103.10.3:8003");
        String filePath = "E:\\tmp\\cmp\\app\\Dockerfile";
        DockerUtil dockerUtil = new DockerUtil("tcp://192.168.189.6:2375");
        List<Image> images = dockerUtil.listImages();
        images.stream().forEach(image -> System.out.println(image.getId()));
        String imageId = dockerUtil.buildImage("E:\\tmp\\cmp\\app\\Dockerfile",
                "nexus.cfn-20230109.com:8444/public/gpu-manager", "v1.0.0");
        System.out.println("Built image ID: " + imageId);

        //dockerUtil.login("admin", "1q2w3e$R", "10.103.10.3:8003");
        ////dockerUtil.removeImage("e45ac70e0a6d");
        //
        ////extracted(dockerUtil);
        //// Tag an image
        //dockerUtil.tagImage("c49ccdef0ab0", "10.103.10.3:8003/repository-1", "v1");
        //// Push an image
        //dockerUtil.pushImage("10.103.10.3:8003", "10.103.10.3:8003/repository-1:v1");
        //// Pull an image
        //dockerUtil.pullImage("10.103.10.3:8003", "repository-1");
    }

    //测试Minio
    @Test
    public void testMinio() {
        String jsonString =
                "{\"description\" : \"There was problem deleting a user. Consult the response body for more details\"}";

        // 正则表达式匹配 description 的值
        List<String> regexList = List.of("\"description\"\\s*:\\s*\"([^\"]*)\"",
                                         "\"name\"\\s*:\\s*\"([^\"]*)\"",
                                         "\"summary\"\\s*:\\s*\"([^\"]*)\"",
                                         "(\"tags\"\\s*:\\s*\\[)(\\\\\".*?\\\\\")(\\])"
        );
        //replace(regex, jsonString);
    }

    //翻译文档
    @Test
    public void testMachineTranslation() {
        List<String> regexList = List.of("\"description\"\\s*:\\s*\"([^\"]*)\"",
                                         "\"name\"\\s*:\\s*\"([^\"]*)\"",
                                         "\"summary\"\\s*:\\s*\"([^\"]*)\"",
                                         "\"tags\"\\s*:\\s*\\[([^\\]]*)\\]"
        );
        //从文档中读取每一行的英文单词，并翻译成中文
        try {
            List<String> output = new ArrayList<>();
            List<String> allLines = Files.readAllLines(Paths.get("E:\\cloud_star\\240104裸设备GPU算力调度插件\\nexus_api.json"));
            allLines.stream().forEach(line -> {
                String replace = line;
                for (String regex : regexList) {
                    replace = replace(regex, line);
                    if (!line.equals(replace)) {
                        break;
                    }
                }
                output.add(replace);
            });

            // 保存
            writer(Paths.get("E:\\cloud_star\\240104裸设备GPU算力调度插件\\nexus_api_zh.json"), output, StandardOpenOption.WRITE);
        } catch (IOException e) {
            log.error("读取文件失败", e);
        }
    }

    /**
     * replace
     *
     * @param regex 正则表达式
     * @param jsonString json字符串
     */
    private static String replace(String regex, String jsonString) {
        if (StrUtil.isBlank(regex) || StrUtil.isBlank(jsonString)) {
            return jsonString;
        }
        Pattern descriptionPattern = Pattern.compile(regex);
        Matcher descriptionMatcher = descriptionPattern.matcher(jsonString);

        if (descriptionMatcher.find()) {
            String description = null;
            try {
                description = descriptionMatcher.group(1);
                String startTag = "\"tags\" : [ \"";
                String endTag = "\"";
                int startIndex = jsonString.indexOf(startTag);
                int endIndex = jsonString.indexOf(endTag, startIndex);

                if (startIndex != -1 && endIndex != -1) {
                    description = jsonString.substring(startIndex + startTag.length(), endIndex);
                }
            } catch (Exception e) {
                if (StrUtil.isBlank(description)) {
                    log.error("正则表达式匹配失败{}", jsonString);
                    return jsonString;
                }
            }
            if ("body".equals(description) || StrUtil.isBlank(description) || (jsonString.contains("name") && jsonString.contains(","))) {
                return jsonString;
            }
            description = description.replaceAll("\"", "");
            if (MachineTranslationUtil.itsChinese(description)) {
                return jsonString;
            }
            String chinese = MachineTranslationUtil.toChinese(description);
            if (StrUtil.isBlank(chinese)) {
                return jsonString;
            }
            chinese = chinese.replaceAll("\"", "");
            return jsonString.replace(description, chinese);
        }
        return jsonString;
    }

    private static void writer(Path path, List<String> inputList, OpenOption... options) {
        try (BufferedWriter writer = Files.newBufferedWriter(path, StandardCharsets.UTF_8, options)) {
            for (String line : inputList) {
                if (StrUtil.isNotBlank(line)) {
                    writer.write(line);
                }
                writer.newLine();
            }
        } catch (Exception e) {
            log.error("写入文件异常: {}", e.getMessage());
        }
    }


    //测试BigDecimal最大容量
    @Test
    public void testBigDecimal() {
        BigDecimal bd1 = new BigDecimal("123456789012345678901234567890.12345678901234567890");

        //long 的最大值
        long maxLong = Long.MAX_VALUE;
        //BigDecimal 的最大值
        BigDecimal maxBigDecimal = new BigDecimal(maxLong);
        //BigDecimal 的最小值
        BigDecimal minBigDecimal = new BigDecimal(Long.MIN_VALUE);
        maxBigDecimal.toString();
    }

    //测试匹配字符串
    @Test
    public void testMatch() throws IOException {
        String[] moduleSids = "BG0403,BG0303".split(",");
        List<String> authList = Files.readAllLines(Paths.get("E:\\cloud_star\\240415东南大学定制化\\课题功能\\input.txt"));
        boolean b = Arrays.stream(Objects.requireNonNull(moduleSids))
                          .anyMatch(authList::contains);
        System.out.println(b);
    }

    //测试获取环境变量
    @Test
    public void testGetEnv() {

        System.out.println(TemplateConst.RES_AUTHORITY);
    }


}
